/**
 * 
 */
package com.juliashine.db.spring;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * @author Juliashine	2011-4-29 
 * 
 */
public class DataSourceUtils {

	private static final Log logger = LogFactory.getLog(DataSourceUtils.class);
	
	public static Connection getConnection(DataSource dataSource) throws SQLException {
		try {
			return doGetConnection(dataSource);
		}
		catch (SQLException ex) {
			throw ex;
		}
	}
	
	public static Connection doGetConnection(DataSource dataSource) throws SQLException {
//		Assert.notNull(dataSource, "No DataSource specified");

//		ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
//		if (conHolder != null && (conHolder.hasConnection() || conHolder.isSynchronizedWithTransaction())) {
//			conHolder.requested();
//			if (!conHolder.hasConnection()) {
//				logger.debug("Fetching resumed JDBC Connection from DataSource");
//				conHolder.setConnection(dataSource.getConnection());
//			}
//			return conHolder.getConnection();
//		}
		// Else we either got no holder or an empty thread-bound holder here.

		logger.debug("Fetching JDBC Connection from DataSource");
		Connection con = dataSource.getConnection();

//		if (TransactionSynchronizationManager.isSynchronizationActive()) {
//			logger.debug("Registering transaction synchronization for JDBC Connection");
//			// Use same Connection for further JDBC actions within the transaction.
//			// Thread-bound object will get removed by synchronization at transaction completion.
//			ConnectionHolder holderToUse = conHolder;
//			if (holderToUse == null) {
//				holderToUse = new ConnectionHolder(con);
//			}
//			else {
//				holderToUse.setConnection(con);
//			}
//			holderToUse.requested();
//			TransactionSynchronizationManager.registerSynchronization(
//					new ConnectionSynchronization(holderToUse, dataSource));
//			holderToUse.setSynchronizedWithTransaction(true);
//			if (holderToUse != conHolder) {
//				TransactionSynchronizationManager.bindResource(dataSource, holderToUse);
//			}
//		}

		return con;
	}
	
	
	public static void releaseConnection(Connection con, DataSource dataSource) {
		try {
			doReleaseConnection(con, dataSource);
		}
		catch (SQLException ex) {
			logger.debug("Could not close JDBC Connection", ex);
		}
		catch (Throwable ex) {
			logger.debug("Unexpected exception on closing JDBC Connection", ex);
		}
	}
	
	public static void doReleaseConnection(Connection con, DataSource dataSource) throws SQLException {
		if (con == null) {
			return;
		}

//		if (dataSource != null) {
//			ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
//			if (conHolder != null && connectionEquals(conHolder, con)) {
//				// It's the transactional Connection: Don't close it.
//				conHolder.released();
//				return;
//			}
//		}
//
//		// Leave the Connection open only if the DataSource is our
//		// special SmartDataSoruce and it wants the Connection left open.
//		if (!(dataSource instanceof SmartDataSource) || ((SmartDataSource) dataSource).shouldClose(con)) {
//			logger.debug("Returning JDBC Connection to DataSource");
//			con.close();
//		}
		
		con.close();
	}
	
	public static void applyTimeout(Statement stmt, DataSource dataSource, int timeout) throws SQLException {
//		Assert.notNull(stmt, "No Statement specified");
//		Assert.notNull(dataSource, "No DataSource specified");
//		ConnectionHolder holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
//		if (holder != null && holder.hasTimeout()) {
//			// Remaining transaction timeout overrides specified value.
//			stmt.setQueryTimeout(holder.getTimeToLiveInSeconds());
//		}
//		else if (timeout > 0) {
//			// No current transaction timeout -> apply specified value.
//			stmt.setQueryTimeout(timeout);
//		}
	}
	
	
}
